package com.vhall.component.service.data.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.vhall.component.entity.data.enums.DpWatchTimeTopEnum;
import com.vhall.component.entity.data.enums.DurationDistributionEnum;
import com.vhall.component.entity.data.vo.*;
import com.vhall.component.entity.export.ExportEntity;
import com.vhall.component.entity.export.enums.ExportTypeInfoEnum;
import com.vhall.component.entity.export.vo.ExportUvPreviewPageReqVO;
import com.vhall.component.entity.interactive.enums.DataMarketTypeEnum;
import com.vhall.component.entity.interactive.vo.DataMarketBaseReqVo;
import com.vhall.component.entity.interactive.vo.QaExportReqVo;
import com.vhall.component.entity.room.dto.RoomsEntityDTO;
import com.vhall.component.entity.room.enums.TerminalEnum;
import com.vhall.component.entity.tag.vo.PageChannelListRspVO;
import com.vhall.component.framework.common.constant.CommonConstant;
import com.vhall.component.framework.common.exception.BusinessException;
import com.vhall.component.framework.common.utils.CollectionUtils;
import com.vhall.component.plugin.common.constant.ConstStr;
import com.vhall.component.plugin.common.exception.BizErrorCode;
import com.vhall.component.plugin.common.support.Token;
import com.vhall.component.plugin.common.support.TokenThreadLocal;
import com.vhall.component.plugin.common.utils.BeanCopyUtil;
import com.vhall.component.plugin.common.utils.RandomUtil;
import com.vhall.component.service.data.DataExportService;
import com.vhall.component.service.data.DataService;
import com.vhall.component.service.export.ExportService;
import com.vhall.component.service.room.RoomInnerService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Preconditions;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 导出相关
 *
 * @author kainan.li
 * @date 2021-04-06 19:01:15
 */
@Slf4j
@Service
public class DataExportServiceImpl implements DataExportService {

    private static final String IL_ID = "il_id";
    private static final String ACCOUNT_ID = "account_id";
    private static final String START_TIME = "start_time";
    private static final String END_TIME = "end_time";

    @Autowired
    private RoomInnerService roomInnerService;

    @Autowired
    private ExportService exportService;

    @Value("${paas.apps.lite.appId}")
    public String appId;


    @Value("${vhall.export.type:csv}")
    private String exportType;

    @Autowired
    private DataService dataService;
    public static final DateTimeFormatter NORM_DATETIME_PATTERN = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);

    @Override
    public ExportListRspVO exportListAction(DataExportParamVO reqVO) {
        if (StringUtils.isNotBlank(reqVO.getRoomId())) {
            RoomsEntityDTO ilInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
            if (null == ilInfo) {
                throw new BusinessException(BizErrorCode.EMPTY_ROOM);
            } else {
                reqVO.setIlId(ilInfo.getIlId());
            }
        }
        if (reqVO.getPage() == null) {
            reqVO.setPage(0);
        }
        if (reqVO.getPageSize() == null) {
            reqVO.setPageSize(10);
        }
        if (reqVO.getIlId() != null) {
            RoomsEntityDTO ilInfo = roomInnerService.getRoomInfoByIlId(reqVO.getIlId().toString());
            if (null == ilInfo) {
                throw new BusinessException(BizErrorCode.EMPTY_ROOM);
            }
        }
        int currPage = reqVO.getPage() == 0 ? 1 : reqVO.getPage();
        int pageSize = reqVO.getPageSize() == 10 ? 10 : reqVO.getPageSize();
        int offset = (currPage - 1) * pageSize;
        reqVO.setOffset(offset);
        List<DataExportRspVO> uprv = exportService.getAllInfo(reqVO);
        for (DataExportRspVO derv : uprv) {
            derv.setFileUrl(derv.getOssFile());
        }
        Integer total = exportService.getAllInfoNum(reqVO);
        ExportListRspVO rspVO = new ExportListRspVO();
        rspVO.setCurrentPage(currPage);
        rspVO.setPerPage(pageSize);
        rspVO.setTotal(total);
        rspVO.setPath("/");
        Integer lastPage = total % pageSize == 0 ? total / pageSize : (total / pageSize) + 1;
        rspVO.setLastPage(lastPage);
        Integer firstItem = offset + 1;
        rspVO.setFrom(firstItem);
        int lastItem = firstItem + total - 1;
        rspVO.setTo(Math.min(currPage * pageSize, lastItem));
        rspVO.setFirstPageUrl(getUrl(1));
        rspVO.setLastPageUrl(getUrl(lastPage));
        if (lastPage > currPage) {
            rspVO.setLastPageUrl(getUrl(currPage + 1));
        }
        if (currPage > 1) {
            rspVO.setPrevPageUrl(getUrl(currPage - 1));
        }
        rspVO.setData(uprv);
        return rspVO;
    }

    @Override
    public String exportPvAction(DataExportParamVO reqVO) {
        String beginTime = reqVO.getStartTime() == null ? "2020-01-01" : reqVO.getStartTime();
        String endTime = reqVO.getEndTime();
        Integer ilId = getIlId(reqVO);
        if (reqVO.getStatus() != 1 && reqVO.getStatus() != 2 && reqVO.getStatus() != 3) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }
        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATETIME_PATTERN);
        Map<String, Object> map = new HashMap<>(4);
        map.put("1", "All");
        map.put("2", "Live");
        map.put("3", "Record");
        JSONObject jo = new JSONObject();
        jo.put(IL_ID, ilId);
        if (beginTime.length() == 10) {
            beginTime = beginTime + " " + "00:00:00";
        }

        if (StringUtils.isNotBlank(endTime)) {
            if (endTime.length() == 10) {
                endTime = endTime + " " + "23:59:59";
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            SimpleDateFormat sdf1 = new SimpleDateFormat(CommonConstant.DATETIME_FORMAT);
            endTime = sdf1.format(now);
        }
        jo.put(ACCOUNT_ID, reqVO.getAccountId());
        jo.put(START_TIME, beginTime);
        jo.put(END_TIME, endTime);
        jo.put("status", reqVO.getStatus());
        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(ilId);
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.parseInt(reqVO.getAccountId()));
        ee.setFileName(map.get(reqVO.getStatus().toString()) + "StatRoomsPvList" + df.format(new Date()) + reqVO.getAccountId());
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_PV.getTitle());
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_PV.getCallback());
        exportService.createExport(ee);
        return JSON.toJSONString(ee);
    }

    @Override
    public String exportUvAction(DataExportParamVO reqVO) {
        reqVO.setEndTime(setReqEndTime(reqVO.getEndTime()));
        Token account = TokenThreadLocal.getToken();
        Integer ilId = getIlId(reqVO);
        reqVO.setAccountId(String.valueOf(account.getAccountId() == null ? 0 : account.getAccountId()));
        if (reqVO.getStatus() != 1 && reqVO.getStatus() != 2 && reqVO.getStatus() != 3) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }

        Map<String, String> map = new HashMap<>(4);
        map.put("1", "All");
        map.put("2", "Live");
        map.put("3", "Record");
        JSONObject jo = new JSONObject();
        jo.put(IL_ID, ilId);
        jo.put(ACCOUNT_ID, reqVO.getAccountId());
        jo.put(START_TIME, reqVO.getStartTime());
        jo.put(END_TIME, reqVO.getEndTime());
        jo.put("type", reqVO.getStatus());
        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(ilId);
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.parseInt(reqVO.getAccountId()));

        RoomsEntityDTO ilInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());

        String fileName = MessageFormat.format("{0}-{1}-{2}", ilInfo.getSubject(), "观看人数", getTimeAndRandom());
        ee.setFileName(fileName);
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_UV.getTitle());
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_UV.getCallback());
        exportService.createExport(ee);
        return JSON.toJSONString(ee);
    }

    @Override
    public Boolean exportMessage(ExportMessageReqVO reqVO, Integer accountId) {
        String roomId = reqVO.getRoomId();
        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(roomId);
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        String beginTime = reqVO.getBeginTime() == null ? "2020-01-01" : reqVO.getBeginTime();
        String endTime = reqVO.getEndTime();
        int filterStatus = reqVO.getFilterStatus() == null ? 0 : reqVO.getFilterStatus();
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern(DatePattern.PURE_DATETIME_PATTERN);

        String fileName = MessageFormat.format("{0}-{1}-{2}"
                , roomInfo.getSubject()
                , filterStatus == 0 ? "未被过滤的消息" : "被过滤消息"
                , getTimeAndRandom());
        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setAccountId(accountId);
        ee.setFileName(fileName);
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_MESSAGE.getTitle());
        // 消息服务要求精确到时分秒
        if (beginTime.length() == 10) {
            beginTime = beginTime + " " + ConstStr.TIME_ZERO;
        }
        if (StringUtils.isNotBlank(endTime)) {
            // 判断格式
            if (endTime.length() == 10) {
                endTime = endTime + " " + ConstStr.TIME_FULL;
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            endTime = NORM_DATETIME_PATTERN.format(now);
        }

        if (StringUtils.isNotBlank(endTime)) {
            if (endTime.length() == 10) {
                endTime = endTime + " " + "23:59:59";
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            endTime = NORM_DATETIME_PATTERN.format(now);
        }
        Map<String, Object> params = new HashMap<>(8);
        params.put(ACCOUNT_ID, accountId);
        params.put(IL_ID, roomInfo.getIlId());
        params.put(START_TIME, beginTime);
        params.put(END_TIME, endTime);
        params.put("filter_status", filterStatus);
        ee.setRoomId(roomId);
        ee.setParams(JSON.toJSONString(params));
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_MESSAGE.getCallback());
        return exportService.createExport(ee);
    }

    /**
     * 导出预约数据
     * @param reqVO
     * @param accountId
     * @return
     */
    public Boolean exportReservation(ExportReservationReqVO reqVO, Integer accountId) {
        String roomId = reqVO.getRoomId();

        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(roomId);
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        String beginTime = reqVO.getBeginTime() == null ? "2020-01-01" : reqVO.getBeginTime();
        String endTime = reqVO.getEndTime();

        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern(DatePattern.PURE_DATETIME_PATTERN);

        String fileName = MessageFormat.format("{0}-{1}-{2}"
                , roomInfo.getSubject()
                , "预约数据"
                , getTimeAndRandom());

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setAccountId(accountId);
        ee.setFileName(fileName);
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_RESERVATION.getTitle());

        // 消息服务要求精确到时分秒
        if (beginTime.length() == 10) {
            beginTime = beginTime + " " + ConstStr.TIME_ZERO;
        }
        if (StringUtils.isNotBlank(endTime)) {
            // 判断格式
            if (endTime.length() == 10) {
                endTime = endTime + " " + ConstStr.TIME_FULL;
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            endTime = NORM_DATETIME_PATTERN.format(now);
        }

        if (StringUtils.isNotBlank(endTime)) {
            if (endTime.length() == 10) {
                endTime = endTime + " " + "23:59:59";
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            endTime = NORM_DATETIME_PATTERN.format(now);
        }
        Map<String, Object> params = new HashMap<>(8);
        params.put(ACCOUNT_ID, accountId);
        params.put(IL_ID, roomInfo.getIlId());
        params.put(START_TIME, beginTime);
        params.put(END_TIME, endTime);

        ee.setRoomId(roomId);
        ee.setParams(JSON.toJSONString(params));
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_RESERVATION.getCallback());

        return exportService.createExport(ee);
    }


    @Override
    public Boolean exportQa(QaExportReqVo reqVO) {
        String roomId = reqVO.getRoomId();
        String startTime = reqVO.getBeginTime();
        String endTime = reqVO.getEndTime();
        Token token = TokenThreadLocal.getToken();
        Integer accountId = token.getAccountId();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSS");
        String time = sdf.format(new Date());
        String fileName = time + "问答记录" + time;
        RoomsEntityDTO room = roomInnerService.getRoomInfo(roomId);
        if (null == room) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }
        String beginTime = startTime + " " + ConstStr.TIME_ZERO;
        String overTime = endTime + " " + ConstStr.TIME_FULL;

        ExportEntity ee = new ExportEntity();
        ee.setExport("qa");
        ee.setIlId(room.getIlId());
        ee.setAccountId(accountId);
        ee.setSourceId("");
        ee.setFileName(fileName);
        List<String> titles = new ArrayList<>();
        titles.add("类型");
        titles.add("账号");
        titles.add("昵称");
        titles.add("角色");
        titles.add("问答内容");
        titles.add("私密");
        titles.add("状态");
        titles.add("同问人数");
        titles.add("更新时间");
        ee.setTitle(JSON.toJSONString(titles));
        Map<String, Object> params = new HashMap<>(8);
        params.put("app_id", appId);
        params.put("room_id", room.getRoomId());
        params.put(START_TIME, beginTime);
        params.put(END_TIME, overTime);
        ee.setParams(JSON.toJSONString(params));
        ee.setRoomId(roomId);
        ee.setExt(exportType);
        ee.setCallback("qaService:getQaExportData");
        return exportService.createExport(ee);
    }

    @Override
    public void exportDataMarket(DataMarketBaseReqVo reqVO, HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 用个List<Map>装表格的所有内容
        ArrayList<Map<String, Object>> rows = new ArrayList<>();

        String fileName = assemblyDatas(reqVO, rows);
        String fileNameUrl = URLEncoder.encode(fileName, "UTF-8");

        // 通过工具类创建writer
        ExcelWriter writer = ExcelUtil.getWriter("xlsx".equalsIgnoreCase(exportType));
        // 一次性写出内容
        writer.write(rows, true);
        // 此处的response.setContentType 和教程里的不同

        String contentType = "";
        if ("csv".equals(exportType)) {
            contentType = "text/csv";
        } else if ("xls".equals(exportType)) {
            contentType = "application/vnd.ms-excel";
        } else if ("xlsx".equals(exportType)) {
            contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        }

        response.setContentType(contentType);
        response.setHeader("Content-disposition", "attachment;filename=" + fileNameUrl + ";" + "filename*=utf-8''" + fileNameUrl);
        // 输出流
        ServletOutputStream servletOutputStream = response.getOutputStream();
        writer.flush(servletOutputStream, true);
        // 关闭writer，释放内存
        writer.close();
        // 关闭输出Servlet流
        IoUtil.close(servletOutputStream);

    }

    @Override
    public Boolean exportWatchPvH5AddApp(DataExportParamVO reqVO) {
        dealWatchPvH5AddApp(reqVO, "");
        return true;
    }

    private void dealWatchPvH5AddApp(DataExportParamVO reqVO, String terminals) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        if (reqVO.getStatus() != 1 && reqVO.getStatus() != 2 && reqVO.getStatus() != 3) {
            throw new BusinessException(BizErrorCode.BIZ_INVALID_PARAM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);


        terminals = StringUtils.join(Arrays.asList(TerminalEnum.IOSSDK.getValue(), TerminalEnum.ANDROIDSDK.getValue(), TerminalEnum.JSWAP.getValue()), ",");
        JSONObject jo = getJsonObject(reqVO, terminals, beginTime, endTime, roomInfo);


        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-观看次数-" + df.format(new Date()) + "-" + number);
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_PV_H5_APP.getTitle());
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_PV_H5_APP.getCallback());

        exportService.createExport(ee);
    }

    @NotNull
    private JSONObject getJsonObject(DataExportParamVO reqVO, String terminals, String beginTime, String endTime, RoomsEntityDTO roomInfo) {
        JSONObject jo = new JSONObject();
        jo.put(IL_ID, roomInfo.getIlId());
        if (beginTime.length() == 10) {
            beginTime = beginTime + " " + "00:00:00";
        }

        if (StringUtils.isNotBlank(endTime)) {
            if (endTime.length() == 10) {
                endTime = endTime + " " + "23:59:59";
            }
        } else {
            LocalDateTime now = LocalDateTime.now();
            SimpleDateFormat sdf1 = new SimpleDateFormat(CommonConstant.DATETIME_FORMAT);
            endTime = sdf1.format(now);
        }


        jo.put(START_TIME, beginTime);
        jo.put(END_TIME, endTime);
        jo.put("status", reqVO.getStatus() == null ? 0 : reqVO.getStatus());
        jo.put("room_id", roomInfo.getRoomId());
        jo.put("terminals", terminals);
        return jo;
    }

    private Integer getIlId(DataExportParamVO reqVO) {
        Integer ilId;
        if (StringUtils.isNotBlank(reqVO.getRoomId())) {
            RoomsEntityDTO ilInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
            if (null == ilInfo) {
                throw new BusinessException(BizErrorCode.EMPTY_ROOM);
            } else {
                ilId = ilInfo.getIlId();
            }
        } else {
            ilId = null;
        }
        return ilId;
    }

    @Override
    public Boolean exportWatchPvApp(DataExportParamVO reqVO) {
        dealWatchPvH5AddApp(reqVO, "4,5");
        return true;
    }


    @Override
    public Boolean exportProduct(DataExportParamVO reqVO) {

        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);
        JSONObject jo = getJsonObject(reqVO, "", beginTime, endTime, roomInfo);

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-金融产品-" + df.format(new Date()) + "-" + number);
        ee.setTitle("['产品代码', '产品名称', '推屏次数', '推屏时长（秒）', '点击次数', '点击人数']");
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback("roomGoodsService:export");
        ee.setType(8);

        exportService.createExport(ee);
        return true;
    }

    @Override
    public Boolean exportProductClick(DataExportParamVO reqVO) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);
        JSONObject jo = getJsonObject(reqVO, "", beginTime, endTime, roomInfo);

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-金融产品(导出点击详情)-" + df.format(new Date()) + "-" + number);
        ee.setTitle("['产品代码', '产品名称', '昵称', '手机号', '客户号', '点击时间']");
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback("roomGoodsService:exportClick");
        ee.setType(8);

        exportService.createExport(ee);
        return true;
    }

    @Override
    public Boolean exportPendant(DataExportParamVO reqVO) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);
        JSONObject jo = getJsonObject(reqVO, "", beginTime, endTime, roomInfo);

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-推屏挂件-" + df.format(new Date()) + "-" + number);
        ee.setTitle("['挂件名称','挂件类型', '推屏次数', '推屏时长（秒）', '点击次数', '点击人数']");
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback("other:exportPendantsList");

        exportService.createExport(ee);
        return true;
    }

    @Override
    public Boolean exportPendantClick(DataExportParamVO reqVO) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);
        JSONObject jo = getJsonObject(reqVO, "", beginTime, endTime, roomInfo);

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-推屏挂件(点击详情)-" + df.format(new Date()) + "-" + number);
        ee.setTitle("['挂件名称', '挂件类型', '昵称', '手机号', '客户号', '点击时间']");
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback("other:exportPendantsClick");

        exportService.createExport(ee);
        return true;
    }

    @Override
    public Boolean exportplayVolumeTrend(DataExportParamVO reqVO) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);
        JSONObject jo = getJsonObject(reqVO, "", beginTime, endTime, roomInfo);

        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(Integer.valueOf(reqVO.getAccountId()));
        int number = ThreadLocalRandom.current().nextInt(1000, 10000);
        ee.setFileName(roomInfo.getSubject() + "-播放量趋势-" + df.format(new Date()) + "-" + number);
        ee.setTitle("['短视频ID', '短视频标题', '日期', '累计播放量', '较昨日新增占比']");
        ee.setParams(jo.toJSONString());
        ee.setExt(exportType);
        ee.setCallback("other:exportplayVolumeTrend");

        exportService.createExport(ee);
        return true;
    }

    @Override
    public Boolean exportUvPreviewPage(ExportUvPreviewPageReqVO reqVO, Integer accountId) {
        Preconditions.checkArgument(StringUtils.isNotBlank(reqVO.getRoomId()), "room_id 不能为空！");
        String beginTime = reqVO.getStartTime();
        String endTime = reqVO.getEndTime();


        RoomsEntityDTO roomInfo = roomInnerService.getRoomInfo(reqVO.getRoomId());
        if (null == roomInfo) {
            throw new BusinessException(BizErrorCode.EMPTY_ROOM);
        }

        SimpleDateFormat df = new SimpleDateFormat(DatePattern.PURE_DATE_PATTERN);

        DataExportParamVO tempVO = new DataExportParamVO();
        BeanUtil.copyProperties(reqVO,tempVO);
        JSONObject paramsJson = getJsonObject(tempVO, "", beginTime, endTime, roomInfo);
        ExportEntity ee = new ExportEntity();
        ee.setExport(reqVO.getExport());
        ee.setIlId(roomInfo.getIlId());
        ee.setRoomId(reqVO.getRoomId());
        ee.setAccountId(accountId);
        ee.setFileName(roomInfo.getSubject() + "-预告页访问人数-" + df.format(new Date()) + "-" + cn.hutool.core.util.RandomUtil.randomNumbers(4));
        ee.setTitle(ExportTypeInfoEnum.CONSOLE_STAT_UV_PREVIEW_PAGE.getTitle());
        ee.setParams(paramsJson.toJSONString());
        ee.setExt(exportType);
        ee.setCallback(ExportTypeInfoEnum.CONSOLE_STAT_UV_PREVIEW_PAGE.getCallback());

        exportService.createExport(ee);
        return true;
    }


    /**
     * 拼装数据
     */
    private String assemblyDatas(DataMarketBaseReqVo reqVO, ArrayList<Map<String, Object>> rows) {

        String type = reqVO.getType();
        DataMarketTypeEnum parse = DataMarketTypeEnum.parse(type);
        Preconditions.checkArgument(parse != null, "传入类型有误！");
        StringBuilder filename = new StringBuilder();

        switch (parse) {
            case DP_COLUMN:
                buildColumnRowsData(reqVO, rows);
                filename.append(DataMarketTypeEnum.DP_COLUMN.getDescription());
                break;
            case DP_ANCHOR:
                buildAnchorRowsData(reqVO, rows);
                filename.append(DataMarketTypeEnum.DP_ANCHOR.getDescription());
                break;
            case DP_WATCH_TIME_TOP:
                getTop(reqVO, rows);
                filename.append(DataMarketTypeEnum.DP_WATCH_TIME_TOP.getDescription());
                break;
            case DP_USER_VIEW:
                getUserView(reqVO, rows);
                filename.append(DataMarketTypeEnum.DP_USER_VIEW.getDescription());
                break;
            default:
                break;
        }

        return filename.append(".").append(exportType).toString();
    }

    private void buildAnchorRowsData(DataMarketBaseReqVo reqVO, ArrayList<Map<String, Object>> rows) {
        UserParamVO userParamVO = new UserParamVO();
        BeanCopyUtil.copy(reqVO, userParamVO);
        List<DpLiveViewDataResponseVO> allDpColumnLiveViewDataListMain = dataService.getAllDpAnchorLiveViewDataListMain(userParamVO);
        if (CollUtil.isEmpty(allDpColumnLiveViewDataListMain)) {
            return;
        }
        // 拿取表格里需要的数据
        int num = 0;
        for (DpLiveViewDataResponseVO data : allDpColumnLiveViewDataListMain) {
            num = num + 1;
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("TOP", num);
            row.put("主播名称", data.getSubject());
            row.put("直播场次", data.getLiveNumber());
            row.put("直播场次占比", data.getLiveSessionPercent());
            row.put("累计观看总人数", data.getAccumulatedNumberOfViewers());
            row.put("累计观看次数", data.getAccumulatedViews());
            row.put("人均观看直播时长（分）", data.getAvgWatchDurationMins());
            rows.add(row);
        }
    }

    private void buildColumnRowsData(DataMarketBaseReqVo reqVO, ArrayList<Map<String, Object>> rows) {
        UserParamVO userParamVO = new UserParamVO();
        BeanCopyUtil.copy(reqVO, userParamVO);
        List<DpLiveViewDataResponseVO> allDpColumnLiveViewDataListMain = dataService.getAllDpColumnLiveViewDataListMain(userParamVO);
        if (CollUtil.isEmpty(allDpColumnLiveViewDataListMain)) {
            return;
        }
        // 拿取表格里需要的数据
        int num = 0;
        for (DpLiveViewDataResponseVO data : allDpColumnLiveViewDataListMain) {
            num = num + 1;
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("TOP", num);
            row.put("栏目", data.getSubject());
            row.put("直播场次", data.getLiveNumber());
            row.put("直播场次占比", data.getLiveSessionPercent());
            row.put("累计观看总人数", data.getAccumulatedNumberOfViewers());
            row.put("累计观看次数", data.getAccumulatedViews());
            row.put("人均观看直播时长（分）", data.getAvgWatchDurationMins());
            rows.add(row);
        }
    }

    private void getUserView(DataMarketBaseReqVo reqVO, ArrayList<Map<String, Object>> rows) {
        UserParamVO userParamVO = new UserParamVO();
        BeanCopyUtil.copy(reqVO, userParamVO);
        List<UserViewDurationDistributionRspVO> dpUserViewDurationDistribution = dataService.getDpUserViewDurationDistribution(userParamVO);

        if (CollectionUtils.isEmpty(dpUserViewDurationDistribution)) {
            return;
        }

        // 拿取表格里需要的数据
        int num = 0;
        for (UserViewDurationDistributionRspVO distributionRspVO : dpUserViewDurationDistribution) {

            num = num + 1;
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("观看时长", DurationDistributionEnum.getDescriptionByKey(distributionRspVO.getKey()));
            row.put("观看人数", distributionRspVO.getNum());
            rows.add(row);

        }

    }

    private void getTop(DataMarketBaseReqVo reqVO, ArrayList<Map<String, Object>> rows) {
        UserParamVO userParamVO = new UserParamVO();
        BeanCopyUtil.copy(reqVO, userParamVO);
        List<DpWatchTimeTopRspVO> dpWatchTimeTop = dataService.getDpWatchTimeTop(userParamVO);
        if (CollectionUtils.isEmpty(dpWatchTimeTop)) {
            return;
        }

        // 拿取表格里需要的数据
        int num = 0;
        for (DpWatchTimeTopRspVO dpWatchTimeTopRspVO : dpWatchTimeTop) {

            num = num + 1;
            Map<String, Object> row = new LinkedHashMap<>();
            row.put("观看时段", DpWatchTimeTopEnum.getDescription(dpWatchTimeTopRspVO.getBtime()));
            row.put("观看人数（实际）", dpWatchTimeTopRspVO.getOriginal());
            rows.add(row);

        }

    }

    private String getUrl(Integer page) {
        if (page <= 0) {
            page = 1;
        }
        return "/?page=" + page;
    }

    public String setReqEndTime(String endTime) {
        if (StringUtils.isNotBlank(endTime)) {
            if (endTime.contains(ConstStr.TIME_ZERO)) {
                endTime = endTime.replace(ConstStr.TIME_ZERO, ConstStr.TIME_FULL);
            } else {
                endTime = endTime + " " + ConstStr.TIME_FULL;
            }
        }
        return endTime;
    }

    private String getTimeAndRandom() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 获取1000到9999的随机数
        int random = RandomUtil.getRandomNum(1000, 9999);
        return LocalDateTime.now().format(formatter) + random;
    }

}